
#ifndef	__QDX_PACKET_H__
#define	__QDX_PACKET_H__

#include	<cstdio>
#include	<string>

#include	"qdxc/limit.h"
#include	"qdxc/types.h"

#pragma pack(1)

struct	message_id_t
{
	unsigned int	m_iDaemonID     :16;     /* machine id where this packet sent from */
	unsigned int	m_iClientID     :16;     /* connect id of process where this packet sent from */
	unsigned int	m_iMessageSerial:32;     /* serial of Message */

	std::string	toString ( void ) const
	{
		char	szResult [ 256 ];
		sprintf ( szResult, "%d,%d,%d", m_iDaemonID, m_iClientID, m_iMessageSerial );
		return	std::string( szResult );
	};
	
	bool	operator== ( const struct message_id_t& id ) const 
	{
		if ((m_iDaemonID == id.m_iDaemonID) && 
			(m_iClientID == id.m_iClientID) && 
			(m_iMessageSerial == id.m_iMessageSerial))
		{
			return	true;
		}
		
		return	false;
	};
	
	bool	operator< ( const struct message_id_t& id) const
	{
		if (m_iDaemonID < id.m_iDaemonID)
		{
			return	true;
		}
		else if (m_iDaemonID > id.m_iDaemonID)
		{
			return	false;
		}
		// here : m_iDaemonID == id.m_iDaemonID
		if (m_iClientID < id.m_iClientID)
		{
			return	true;
		}
		else if (m_iClientID > id.m_iClientID)
		{
			return	 false;
		}
		// here : m_iClientID == id.m_iClientID
		if (m_iMessageSerial < id.m_iMessageSerial)
		{
			return	true;
		}
		else if (m_iMessageSerial > id.m_iMessageSerial)
		{
			return	false;
		}
		// here : m_iMessageSerial == id.m_iMessageSerial
		
		return	false;
	};
};
typedef	struct message_id_t		message_id_t;

struct	packet_id_t
{
	message_id_t	m_message_id;           /* message id */
	unsigned int	m_iPacketSerial :16;    /* serial of packet in Message */
	unsigned int	m_iPacketTotal  :16;    /* total num of pakcets of Message */

	std::string	toString ( void ) const
	{
		char	szResult [ 256 ];
		sprintf ( szResult, "%d,%d,%d,%d/%d", m_message_id.m_iDaemonID, m_message_id.m_iClientID, m_message_id.m_iMessageSerial, m_iPacketSerial, m_iPacketTotal );
		return	std::string( szResult );
	};
	
	void	c_str ( char* pszBuf, unsigned iBufSize )
	{
		int		iReturn = snprintf ( pszBuf, iBufSize - 1, "%d,%d,%d,%d/%d", m_message_id.m_iDaemonID, m_message_id.m_iClientID, m_message_id.m_iMessageSerial, m_iPacketSerial, m_iPacketTotal );
		pszBuf[ iReturn ] = '\0';
	}
	
	bool	operator== ( const struct packet_id_t& id ) const 
	{
		if ((m_message_id == id.m_message_id) && 
			(m_iPacketSerial == id.m_iPacketSerial) &&
			(m_iPacketTotal == id.m_iPacketTotal))
		{
			return	true;
		}
		
		return	false;
	};
	
	bool	operator< ( const struct packet_id_t& id ) const
	{
		if (m_message_id < id.m_message_id)
		{
			return	true;
		}
		else if ( id.m_message_id < m_message_id )
		{
			return	false;
		}
		// here message_id == id.message_id
		if (m_iPacketSerial < id.m_iPacketSerial)
		{
			return	true;
		}
		else if (m_iPacketSerial > id.m_iPacketSerial)
		{
			return	false;
		}
		
		return	false;
	};
};
typedef	struct packet_id_t		packet_id_t;

struct	packet_head_t
{
	unsigned int	m_iTag          :16;    /* tag */
	unsigned int	m_iVersion      :16;    /* packet version */
	unsigned int	m_iHeadSize     :16;    /* sizeof packet_head_t */
	unsigned int	m_iGroupSize    :16;    /* count of groups in group list section */
	unsigned int	m_iPacketFlags  :32;    /* packet type : SYS_PACKET/APP_PACKET*/
	unsigned int	m_iTimeStamp    :32;    /* when this message generated */
	unsigned int	m_iTimeOut      :16;    /* message time out */
	unsigned int	m_iReserve0     :16;
	unsigned int	m_iMessageType  :32;    /* user defined message type */
	packet_id_t     m_packet_id;            /* packet id */
	unsigned int	m_iPacketSize   :32;    /* sizeof packet : */
	
	group_t	m_sender;           /* where this packet sent from */

	group_t	m_target;			/* the target chose from all candidates */
								/* CHANGE.7070501 added by menggang */
	
};
typedef	struct packet_head_t	packet_head_t;

#pragma pack()


/* packet = <packet_head> + <group list> + <data> */

/* maximum groups in list */
#define	QDX_MAX_GROUP_NUM	((32768 - sizeof(packet_head_t)) / sizeof(group_t))

/* packet tag */
#define	PACKET_TAG	0x7890	/* packet tag */
/* packet version */
#define	PACKET_VERSION	0x0010	/* version 1.0 */

/* packet type */
#define	SYS_PACKET              0x08000000           /* system control packet */
#define	STAT_PACKET             0x04000000           /* status change packet */
#define	GROUP_PACKET            0x02000000           /* groupship change packet */
#define	APP_PACKET              0x01000000           /* application data packet */
#define	DATA_PACKET             0x01000000           /* application data packet */
#define	PACKET_TYPE_MASK        0x0F000000

#define	CAST_ALL                0x00000000           /* cast to all destine process */
#define	CAST_HOST               0x00100000           /* cast to one destine process on each machine */
#define	CAST_MACHINE            0x00100000           /* cast to one destine process on each machine */
#define	CAST_ONLYONE            0x00200000           /* cast to only one destine process of all machines */
#define	PACKET_CAST_MASK        0x00F00000

#define	RELIABLE_PACKET         0x00010000           /* reliable packet */
/* CHANGE.7071001 begin : add */
#define	UNRELIABLE_PACKET       0x00020000           /* unreliable packet */
/* CHANGE.7071001   end : add */
#define	PACKET_RELIABILITY_MASK 0x000F0000

#define	REQUEST_PACKET          0x00008000   /* request packet */
#define	RESPONSE_PACKET         0x00004000   /* response packet */
#define	ACK_PACKET              0x00002000   /* acknowledge packet */
#define	NAK_PACKET              0x00003000   /* acknowledge-no packet */
#define	RESPONSE_PACKET_OK      0x00000000   /* AGREE response packet */
#define	RESPONSE_PACKET_NO      0x00001000   /* REFUSE response packet */
#define	PACKET_REQUEST_MASK     0x0000F000

#define	SELF_DISCARD            0x10000000
#define	PACKET_SELF_MASK        0xF0000000

#define	STOP_ON_FAILURE         0x00000000   /* stop on host/client failure */
#define	IGNORE_FAILURE          0x00000100   /* ignore failure host/client, and continue */
#define	PACKET_FAILURE_MASK     0x00000F00

/* Message Type */
/* System Message Type */
#define	MESSAGE_BASE                                 0x0010
#define	MESSAGE_DAEMON_HELLO_REQUEST                 (MESSAGE_BASE + 1)
#define	MESSAGE_DAEMON_HELLO_RESPONSE_OK             (MESSAGE_BASE + 2)
#define	MESSAGE_DAEMON_HELLO_RESPONSE_NO             (MESSAGE_BASE + 3)

#define	MESSAGE_HELLO_MASTER_REQUEST                 (MESSAGE_BASE + 4)
#define	MESSAGE_HELLO_MASTER_RESPONSE_OK             (MESSAGE_BASE + 5)
#define	MESSAGE_BYE_MASTER_REQUEST                   (MESSAGE_BASE + 6)
#define	MESSAGE_BYE_MASTER_RESPONSE_OK               (MESSAGE_BASE + 7)

#define	MESSAGE_HELLO_SEGMENT_LEADER_REQUEST         (MESSAGE_BASE + 8)
#define	MESSAGE_HELLO_SEGMENT_LEADER_RESPONSE_OK     (MESSAGE_BASE + 9)
#define	MESSAGE_BYE_SEGMENT_LEADER_REQUEST           (MESSAGE_BASE + 10)
#define	MESSAGE_BYE_SEGMENT_LEADER_RESPONSE_OK       (MESSAGE_BASE + 11)

#define	MESSAGE_CLIENT_HELLO_REQUEST                 (MESSAGE_BASE + 12)
#define	MESSAGE_CLIENT_HELLO_RESPONSE_OK             (MESSAGE_BASE + 13)
#define	MESSAGE_CLIENT_HELLO_RESPONSE_NO             (MESSAGE_BASE + 14)
#define	MESSAGE_CLIENT_BYE_REQUEST                   (MESSAGE_BASE + 15)
#define	MESSAGE_CLIENT_BYE_RESPONSE_OK               (MESSAGE_BASE + 16)
#define	MESSAGE_CLIENT_BYE_RESPONSE_NO               (MESSAGE_BASE + 17)

#define	MESSAGE_JOIN_GROUP_REQUEST                   (MESSAGE_BASE + 18)
#define	MESSAGE_JOIN_GROUP_RESPONSE_OK               (MESSAGE_BASE + 19)
#define	MESSAGE_JOIN_GROUP_RESPONSE_NO               (MESSAGE_BASE + 20)
#define	MESSAGE_LEAVE_GROUP_REQUEST                  (MESSAGE_BASE + 21)
#define	MESSAGE_LEAVE_GROUP_RESPONSE_OK              (MESSAGE_BASE + 22)
#define	MESSAGE_LEAVE_GROUP_RESPONSE_NO              (MESSAGE_BASE + 23)
#define	MESSAGE_UP_GROUP_REQUEST                     (MESSAGE_BASE + 24)
#define	MESSAGE_DOWN_GROUP_REQUEST                   (MESSAGE_BASE + 25)
#define	MESSAGE_QUERY_GROUP_REQUEST                  (MESSAGE_BASE + 26)
#define	MESSAGE_QUERY_GROUP_RESPONSE_OK              (MESSAGE_BASE + 27)
#define	MESSAGE_QUERY_GROUP_RESPONSE_NO              (MESSAGE_BASE + 28)

#define	MESSAGE_WHOLE_GROUPSHIP_REQUEST              (MESSAGE_BASE + 29)
#define	MESSAGE_WHOLE_GROUPSHIP_RESPONSE             (MESSAGE_BASE + 30)
#define	MESSAGE_WHOLE_GROUPSHIP_UPDATE               (MESSAGE_BASE + 31)

#define	MESSAGE_WHOLE_GROUPSHIP_REPORT               (MESSAGE_BASE + 32)

#define	MESSAGE_DATA_ACK                             (MESSAGE_BASE + 100)
#define	MESSAGE_DATA_NAK                             (MESSAGE_BASE + 101)

#define	MESSAGE_DISCARD_REQUEST                      (MESSAGE_BASE + 102)
#define	MESSAGE_ECHO_REQUEST                         (MESSAGE_BASE + 103)
#define	MESSAGE_ECHO_RESPONSE                        (MESSAGE_BASE + 104)


#define	MESSAGE_MAX_NUMBER                           1024

/* Application Message Type */


////////////////////////////////////////////////////////////////////////


struct	packet_t
{
	packet_head_t   m_head;

	// MUST NOT define ANY variable
	//group_t*        m_pGroups;	// MUST NOT define this variable
	//void*           m_pvData;		// MUST NOT define this variable

	//public operation
public	:
	packet_t()
	{
		memset ( &m_head, 0, sizeof(m_head) );
		//m_pGroups = NULL;
		//m_pvData = NULL;
	};
	
	void	clear ( void ) { memset ( &m_head, 0, sizeof(m_head) ); };
	
	bool	isValidPacket ( void ) { return (PACKET_TAG == m_head.m_iTag); };

	void	setTag ( unsigned short iTag ) { m_head.m_iTag = iTag; };
	unsigned short getTag ( void ) const { return m_head.m_iTag; };
	void	setVersion ( unsigned short iVersion ) { m_head.m_iVersion = iVersion; };
	unsigned short getVersion ( void ) const { return m_head.m_iVersion; };
	void	setHeadSize ( unsigned short iHeadSize ) { m_head.m_iHeadSize = iHeadSize; };
	unsigned short getHeadSize ( void ) const { return m_head.m_iHeadSize; };
	
	void	setTimeStamp ( size_t iTimeStamp ) { m_head.m_iTimeStamp = iTimeStamp; };
	size_t	getTimeStamp ( void ) const { return m_head.m_iTimeStamp; };
	void	setTimeOut ( short iTimeOut ) { m_head.m_iTimeOut = iTimeOut; };
	short	getTimeOut ( void ) const { return short(m_head.m_iTimeOut); };
	
	void	setMessageType ( unsigned iMessageType ) { m_head.m_iMessageType = iMessageType; };
	unsigned	getMessageType ( void ) const { return m_head.m_iMessageType; };
	
	void	setPacketSize ( size_t iPacketSize ) { m_head.m_iPacketSize = iPacketSize; };
	size_t	getPacketSize ( void ) const { return m_head.m_iPacketSize; };
	
	void	setSender ( const char* pszSender ) { strncpy ( m_head.m_sender, pszSender, sizeof(group_t) - 1 ); };
	char*	getSender ( void ) { return (char *)(m_head.m_sender); };
	const char* getSender ( void ) const { return (const char*)(m_head.m_sender); };

	/* CHANGE.7070501 : begin added by menggang */
	void	clearTarget ( void ) { memset ( m_head.m_target, 0, sizeof(group_t) ); }
	void	setTarget ( const char* pszTarget ) { strncpy ( m_head.m_target, pszTarget, sizeof(group_t) - 1 ); };
	char*	getTarget ( void ) { return (char *)(m_head.m_target); };
	const char* getTarget ( void ) const { return (const char*)(m_head.m_target); };
	/* CHANGE.7070501 :   end added by menggang */

	// DATA operations
	void*	getpData ( void ) {
		//void*	m_pvData = (void *)((char *)this + sizeof(packet_head_t) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize);
		void*	m_pvData = (void *)((char *)&m_head + sizeof(packet_head_t) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize);
		
		return	m_pvData;
	};
	void*	getData ( void ) { return getpData(); };
	size_t	getDataSize ( void ) {
		size_t	iHeadSize = sizeof(packet_head_t) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize;
		
		return	(m_head.m_iPacketSize - iHeadSize);
	};
	size_t	getMaxDataSize ( size_t iPacketSize ) {
		return this->getMaxDataSize( iPacketSize, m_head.m_iGroupSize );
	};
	size_t	getMaxDataSize ( size_t iPacketSize, size_t iGroupSize ) {
		return ( iPacketSize - sizeof(packet_head_t) - QDX_MAX_GROUP_NAME_LEN * iGroupSize );
	};
	int		setData ( size_t iPacketSize, const void *pvData, size_t iDataSize )	{
		if (getMaxDataSize(iPacketSize) < iDataSize)
		{
			// OVERFLOW
			return	-1;
		}
		
		if (NULL != pvData)
		{
			//void*	m_pvData = (void *)((char *)this + sizeof(m_head) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize);
			void*	m_pvData = (void *)((char *)&m_head + sizeof(m_head) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize);
			memmove ( m_pvData, pvData, iDataSize );
		}
		
		size_t	iTotalSize = sizeof(packet_head_t) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize + iDataSize;
		this->setPacketSize ( iTotalSize );
		
		return	0;
	};
	void	setDataSize ( size_t iDataSize ) {
		size_t	iTotalSize = sizeof(packet_head_t) + QDX_MAX_GROUP_NAME_LEN * m_head.m_iGroupSize + iDataSize;
		this->setPacketSize ( iTotalSize );
	};
	
	// GROUP operations
	group_t*	getpGroupList ( void ) {
		//group_t*	m_pGroups = (group_t *)( (char *)this + sizeof(m_head) );
		group_t*	m_pGroups = (group_t *)( (char *)&m_head + sizeof(m_head) );
		
		return	m_pGroups;
	};
	const group_t*	getpGroupList ( void ) const {
		//group_t*	m_pGroups = (group_t *)( (char *)this + sizeof(m_head) );
		group_t*	m_pGroups = (group_t *)( (char *)&m_head + sizeof(m_head) );
		
		return	m_pGroups;
	};
	void	addGroup ( const char* pszGroup ) {
		group_t*	pGroups = getpGroupList ();
		group_t&	pGroup = pGroups[ this->getGroupCount() ];
		
		strncpy ( (char *)pGroup, pszGroup, sizeof(group_t) - 1 );
		m_head.m_iGroupSize += 1;
	}
	
	void	setGroupCount ( size_t iGroupCount ) { m_head.m_iGroupSize = iGroupCount; };
	size_t	getGroupCount ( void ) const { return m_head.m_iGroupSize; };
	size_t	getGroupSize ( void ) const { return m_head.m_iGroupSize * QDX_MAX_GROUP_NAME_LEN; };
	
	// ID operations
	void	setClientID ( client_id_t client_id ) { m_head.m_packet_id.m_message_id.m_iClientID = client_id; };
	client_id_t	getClientID ( void ) const { return m_head.m_packet_id.m_message_id.m_iClientID; };
	void	setDaemonID ( daemon_id_t daemon_id ) { m_head.m_packet_id.m_message_id.m_iDaemonID = daemon_id; };
	daemon_id_t	getDaemonID ( void ) const { return m_head.m_packet_id.m_message_id.m_iDaemonID; };
	void	setMessageSerial ( int iMessageSerial ) { m_head.m_packet_id.m_message_id.m_iMessageSerial = iMessageSerial; };
	int		getMessageSerial ( void ) const { return m_head.m_packet_id.m_message_id.m_iMessageSerial; };
	
	void	setPacketSerial ( short iPacketSerial ) { m_head.m_packet_id.m_iPacketSerial = iPacketSerial; };
	short	getPacketSerial ( void ) const { return m_head.m_packet_id.m_iPacketSerial; };
	
	void	setPacketTotal ( short iPacketTotal ) { m_head.m_packet_id.m_iPacketTotal = iPacketTotal; };
	short	getPacketTotal ( void ) const { return m_head.m_packet_id.m_iPacketTotal; };

	void	setMessageID ( message_id_t& message_id ) { m_head.m_packet_id.m_message_id = message_id; };
	message_id_t	getMessageID ( void ) const { return m_head.m_packet_id.m_message_id; };
	
	void	setPacketID ( packet_id_t& packet_id ) { m_head.m_packet_id = packet_id; };
	packet_id_t		getPacketID ( void ) const { return m_head.m_packet_id; };
	
	// flAGS operations
	void	setPacketFlags( unsigned int iPacketFlags ) {m_head.m_iPacketFlags = iPacketFlags; };
	unsigned int getPacketFlags( void ) { return m_head.m_iPacketFlags; };

	void	setSysPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_TYPE_MASK; m_head.m_iPacketFlags |= SYS_PACKET; };
	bool	isSysPacket ( void ) const { return ( SYS_PACKET == (m_head.m_iPacketFlags & PACKET_TYPE_MASK) ); };

	void	setDataPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_TYPE_MASK; m_head.m_iPacketFlags |= DATA_PACKET; };
	bool	isDataPacket ( void ) const { return ( DATA_PACKET == (m_head.m_iPacketFlags & PACKET_TYPE_MASK) ); };

	void	setAppPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_TYPE_MASK; m_head.m_iPacketFlags |= APP_PACKET; };
	bool	isAppPacket ( void ) const { return ( APP_PACKET == (m_head.m_iPacketFlags & PACKET_TYPE_MASK) ); };
	
	void	setRequestPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= REQUEST_PACKET; };
	bool	isRequestPacket ( void ) const { return ( REQUEST_PACKET == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };

	void	setResponsePacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= RESPONSE_PACKET; };
	bool	isResponsePacket ( void ) const { return ( RESPONSE_PACKET == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };
	void	setResponseOKPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= RESPONSE_PACKET_OK; };
	bool	isResponseOKPacket ( void ) const { return ( RESPONSE_PACKET_OK == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };
	void	setResponseNOPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= RESPONSE_PACKET_NO; };
	bool	isResponseNOPacket ( void ) const { return ( RESPONSE_PACKET_NO == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };

	void	setAckPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= ACK_PACKET; };
	bool	isAckPacket ( void ) const { return ( ACK_PACKET == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };
	void	setNakPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_REQUEST_MASK; m_head.m_iPacketFlags |= NAK_PACKET; };
	bool	isNakPacket ( void ) const { return ( NAK_PACKET == (m_head.m_iPacketFlags & PACKET_REQUEST_MASK) ); };
	
	/* CHANGE.7070501 : begin added by menggang */
	void	setCastAllPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_CAST_MASK; m_head.m_iPacketFlags |= CAST_ALL; };
	bool	isCastAllPacket ( void ) const { return ( CAST_ALL == (m_head.m_iPacketFlags & PACKET_CAST_MASK) ); };
	void	setCastMachinePacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_CAST_MASK; m_head.m_iPacketFlags |= CAST_MACHINE; };
	bool	isCastMachinePacket ( void ) const { return ( CAST_MACHINE == (m_head.m_iPacketFlags & PACKET_CAST_MASK) ); };
	void	setCastHostPacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_CAST_MASK; m_head.m_iPacketFlags |= CAST_HOST; };
	bool	isCastHostPacket ( void ) const { return ( CAST_HOST == (m_head.m_iPacketFlags & PACKET_CAST_MASK) ); };
	void	setCastOnlyOnePacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_CAST_MASK; m_head.m_iPacketFlags |= CAST_ONLYONE; };
	bool	isCastOnlyOnePacket ( void ) const { return ( CAST_ONLYONE == (m_head.m_iPacketFlags & PACKET_CAST_MASK) ); };
	/* CHANGE.7070501 : end added by menggang */

	/* CHANGE.7071001 begin : add */
	void	setReliablePacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_RELIABILITY_MASK; m_head.m_iPacketFlags |= RELIABLE_PACKET; };
	bool	isReliablePacket ( void ) const { return ( RELIABLE_PACKET == (m_head.m_iPacketFlags & PACKET_RELIABILITY_MASK) ); };
	void	setUnreliablePacket ( void ) { m_head.m_iPacketFlags &= ~PACKET_RELIABILITY_MASK; m_head.m_iPacketFlags |= UNRELIABLE_PACKET; };
	bool	isUnreliablePacket ( void ) const { return ( UNRELIABLE_PACKET == (m_head.m_iPacketFlags & PACKET_RELIABILITY_MASK) ); };
	/* CHANGE.7071001   end : add */

	void	setStopOnFailure ( void ) { m_head.m_iPacketFlags &= ~PACKET_FAILURE_MASK; m_head.m_iPacketFlags |= STOP_ON_FAILURE; };
	bool	isStopOnFailure ( void ) const { return ( STOP_ON_FAILURE == (m_head.m_iPacketFlags & PACKET_FAILURE_MASK) ); };
	void	setIgnoreFailure ( void ) { m_head.m_iPacketFlags &= ~PACKET_FAILURE_MASK; m_head.m_iPacketFlags |= IGNORE_FAILURE; };
	bool	isIgnoreFailure ( void ) const { return ( IGNORE_FAILURE == (m_head.m_iPacketFlags & PACKET_FAILURE_MASK) ); };

	packet_t&	operator= ( const packet_t& rhs ) { m_head = rhs.m_head; return *this; };
	
	const char*	dump ( void ) { 
		// NO thread-safe 
		return	NULL;
	}
};
typedef	struct packet_t		packet_t;


int		packet_copyHead ( packet_head_t* pPacketTo, packet_head_t* pPacketFrom );
int		packet_clearHead ( packet_head_t* pPacketHead );

const char*	packet_dump ( void *pvPacket );
const char*	packet_getSystemMessageName ( int iMessageType );


#endif	/* __QDX_PACKET_H__ */
